package cn.edu.nju.ws.sview.servlets;

import java.io.IOException;
import java.net.URLDecoder;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashSet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;

import cn.edu.nju.ws.sview.cache.GroupCache;
import cn.edu.nju.ws.sview.cache.URIIDCache;
import cn.edu.nju.ws.sview.cache.URILabelCache;
import cn.edu.nju.ws.sview.cache.UserNameIDCache;
import cn.edu.nju.ws.sview.crawler.Crawler;
import cn.edu.nju.ws.sview.crawler.Element;
import cn.edu.nju.ws.sview.database.DBOperations;
import cn.edu.nju.ws.sview.rdf.BlankNode;
import cn.edu.nju.ws.sview.rdf.Literal;
import cn.edu.nju.ws.sview.rdf.PlainLiteral;
import cn.edu.nju.ws.sview.rdf.Resource;
import cn.edu.nju.ws.sview.rdf.ResourceFactory;
import cn.edu.nju.ws.sview.rdf.TypedLiteral;
import cn.edu.nju.ws.sview.rdf.URIResource;
import cn.edu.nju.ws.sview.reasoning.Atom;
import cn.edu.nju.ws.sview.reasoning.Constant;
import cn.edu.nju.ws.sview.reasoning.GroundAtom;
import cn.edu.nju.ws.sview.reasoning.KnowledgeBase;
import cn.edu.nju.ws.sview.reasoning.Predicate;
import cn.edu.nju.ws.sview.reasoning.Term;
import cn.edu.nju.ws.sview.reasoning.Variable;
import cn.edu.nju.ws.sview.reasoning.reasoner.ViewReasoner;
import cn.edu.nju.ws.sview.util.PropertyList;
import cn.edu.nju.ws.sview.util.URIUtil;
import cn.edu.nju.ws.sview.views.Bookmark;
import cn.edu.nju.ws.sview.views.CustomDataMember;
import cn.edu.nju.ws.sview.views.DataMember;
import cn.edu.nju.ws.sview.views.Entity;
import cn.edu.nju.ws.sview.views.Group;
import cn.edu.nju.ws.sview.views.URIDataMember;
import cn.edu.nju.ws.sview.views.View;
import cn.edu.nju.ws.sview.views.data.EntityBrowsing;
import cn.edu.nju.ws.sview.views.data.EntityManagement;
import cn.edu.nju.ws.sview.views.data.ViewEditing;
import cn.edu.nju.ws.sview.views.data.ViewManagement;
import cn.edu.nju.ws.sview.views.data.ViewEditing.ViewItem;

/**
 * Servlet implementation class ViewServlet
 */
@WebServlet("/ViewServlet")
public class ViewServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	public static final String STATUS_WAIT_DATA= "wait_data"  ;
    public static final String STATUS_WAIT_LABEL ="wait_label";
    public static final String STATUS_STOP = "stop" ;
    public static final String STATUS_UNDOWNLOADED = "undownloaded";
    public static final int REASONING_RESULT_LABEL_FETCH_NUM = 30;
    /*when the result of reasoning is large than 300,stop reasoning to avoid 
     * explosion;
     * */
    public static final int ALTIMATE_REASONING_RESULT = 300;
    /**
     * @see HttpServlet#HttpServlet()
     */
    public ViewServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		String option=null;
		String json=null;
		request.setCharacterEncoding("utf-8");
		response.setCharacterEncoding("utf-8");
		if(request.getParameter("group")!=null){
			json = request.getParameter("group");
			option="group";
		}
		else if(request.getParameter("all")!=null){
			json = request.getParameter("all");
			option="all";
		}
		else if(request.getParameter("available")!=null){
			json = request.getParameter("available");
			option="available";
		}
        else if(request.getParameter("favourite")!=null){
			json = request.getParameter("favourite");
			option="favourite";
		}else if(request.getParameter("trashed")!=null){
			json = request.getParameter("trashed");
			option="trashed";
		}else if(request.getParameter("cancelFavorite")!=null){
			json = request.getParameter("cancelFavorite");
			option="cancelFavorite";
		}else if(request.getParameter("addFavorite")!=null){
			json = request.getParameter("addFavorite");
			option="addFavorite";
		}
		else if(request.getParameter("addTrash")!=null){
			json = request.getParameter("addTrash");
			option="addTrash";
		}
		else if(request.getParameter("cancelTrash")!=null){
			json = request.getParameter("cancelTrash");
			option="cancelTrash";
		}else if(request.getParameter("existBookmark")!=null){
			json = request.getParameter("existBookmark");
			option="existBookmark";
		}
		else if(request.getParameter("storeBookmark")!=null){
			json = request.getParameter("storeBookmark");
			option="storeBookmark";
		}
		else if(request.getParameter("viewDMList")!=null){
			json = request.getParameter("viewDMList");
			option="viewDMList";
		}else if(request.getParameter("viewDMValue")!=null){
			json = request.getParameter("viewDMValue");
			option="viewDMValue";
		}
		else if(request.getParameter("checkAuthor")!=null){
			json = request.getParameter("checkAuthor");
			option="checkAuthor";
		}
		else if(request.getParameter("viewSearch")!=null){
			json = request.getParameter("viewSearch");
			option="viewSearch";
		}
		
		
		if(option.equals("group")){
			String str = URLDecoder.decode(json,"utf-8");
			JSONObject regtJSON = (JSONObject) JSONValue.parse(str);
			String user = (String)regtJSON.get("user") ;
			JSONArray array = new JSONArray();
		     try{
		    	 HashSet<Integer> groups  = GroupCache.getInstance().getGroupIDs(UserNameIDCache.getInstance().getUserID(user)) ;
		    	 for(Integer gid:groups){
		    		 String name = Group.getGroupNameById(gid) ;
		    		 JSONObject jsob =new JSONObject();
		    		 jsob.put("gid", gid) ;
		    		 jsob.put("gname", name) ;
		    		 array.add(jsob) ;
		    	 }
		     }catch(Throwable e){
		    	 e.printStackTrace();
		     }
		     response.getWriter().print(array) ;
		}else if (option.equals("all")){
			String str =  URLDecoder.decode(json,"utf-8");
			JSONObject regtJSON = (JSONObject) JSONValue.parse(str);
			String user = (String)regtJSON.get("user") ;
			String lang = (String)regtJSON.get("lang") ;
			
			int minClassID = Integer.parseInt((String)regtJSON.get("classID")) ;
			
			boolean isInner = Integer.parseInt((String)regtJSON.get("isInner"))==1?true:false ;
			int start = ((Long)regtJSON.get("start")).intValue() ;
			int length = ((Long)regtJSON.get("length")).intValue() ;
			int totalNum  =  0;
			int curstart = start;
			int curlength = length;
			ArrayList<View> views = new ArrayList<View>();
			if (minClassID>0) {
				int popnum = View.getPopViewNum(isInner, minClassID, lang, user);
				if(user!=null){
					int favnum = View.getFavorViewsNum(isInner, minClassID, lang, user);
					int trashnum = View.getTrashedViewsNum(isInner, minClassID, lang, user);
					totalNum = favnum + popnum + trashnum;
//					System.out.println("num:"+favnum+"|"+popnum+"|"+trashnum);
//					System.out.println("0:"+curstart+"|"+curlength);
					if(curstart<favnum && curlength>0){
						views.addAll(View.getFavorViews(isInner, minClassID, lang,user, curstart, curlength));
						curstart += views.size();
						curlength = length - views.size();
					}
//					System.out.println("1:"+curstart+"|"+curlength);
					if(curstart<(favnum + popnum) && curlength>0){
						curstart -= favnum;
						views.addAll(View.getPopViews(isInner, minClassID, lang,user, curstart, curlength));
						curstart = start + views.size();
						curlength = length - views.size();
					}
//					System.out.println("2:"+curstart+"|"+curlength);
					if(curstart<totalNum && curlength>0){
						curstart -= (favnum + popnum);
						views.addAll(View.getTrashedViews(isInner, minClassID, lang,user, curstart, curlength));
						curstart = start + views.size();
						curlength = length - views.size();
					}
//					System.out.println("3:"+curstart+"|"+curlength);
				}else{
					totalNum = popnum;
					views = View.getPopViews(isInner, minClassID, lang,user, start, length);
				}
			}
			JSONArray elements = new JSONArray();
			for(View view:views){
				JSONObject jsob = new JSONObject();
				jsob.put("name", view.getName());
				jsob.put("id",view.getID());
				if(view.getStatus()!=null){
					jsob.put("status", view.getStatus());
				}else{
					jsob.put("status", View.STATUS_POP);
				}
		        elements.add(jsob) ;
			}
    	    JSONObject result = new JSONObject();
    	    result.put("views", elements) ;
    	    result.put("totalNum", totalNum) ;
//    	    System.out.println("all:"+result.toJSONString());
		    response.getWriter().print(result) ;
		}
		else if(option.equals("available")||option.equals("favourite")||option.equals("trashed")){
			String str =  URLDecoder.decode(json,"utf-8");
			JSONObject regtJSON = (JSONObject) JSONValue.parse(str);
			String user = (String)regtJSON.get("user") ;
			String lang = (String)regtJSON.get("lang") ;
			
			int minClassID = Integer.parseInt((String)regtJSON.get("classID")) ;
			
			boolean isInner = Integer.parseInt((String)regtJSON.get("isInner"))==1?true:false ;
			int start = ((Long)regtJSON.get("start")).intValue() ;
			int length = ((Long)regtJSON.get("length")).intValue() ;
			int totalNum  =  0;
			
			if (minClassID>0) {
				if (option.equals("available"))
					totalNum = View.getPopViewNum(isInner, minClassID, lang,
							user);
				else if (option.equals("favourite"))
					totalNum = View.getFavorViewsNum(isInner, minClassID,
							lang, user);
				else if (option.equals("trashed"))
					totalNum = View.getTrashedViewsNum(isInner, minClassID,
							lang, user);
			}

			ArrayList<View> views = new ArrayList<View>();
			if (minClassID > 0) {
				if (option.equals("available")){
					views = View.getPopViews(isInner, minClassID, lang, user,
							start, length);
				}
				else if (option.equals("favourite")){
					views = View.getFavorViews(isInner, minClassID, lang,
							user, start, length);
				}
				else if (option.equals("trashed")){
					views = View.getTrashedViews(isInner, minClassID, lang,
							user, start, length);
				}
				   
			}
			
			JSONArray elements = new JSONArray();
			for(View view:views){
				JSONObject jsob = new JSONObject();
				jsob.put("name", view.getName()) ;
				jsob.put("id",view.getID()) ;
		        elements.add(jsob) ;
			}
    	    JSONObject result = new JSONObject();
    	    result.put("views", elements) ;
    	    result.put("totalNum", totalNum) ;
		    response.getWriter().print(result) ;
 		}else if(option.equals("cancelFavorite")){
			String str = URLDecoder.decode(json,"utf-8");
			JSONObject regtJSON = (JSONObject) JSONValue.parse(str);
 			String user = (String)regtJSON.get("user") ;
 			int viewID = Integer.parseInt((String)regtJSON.get("viewID")) ;
 			int classID = Integer.parseInt((String)regtJSON.get("classID")) ;
 			boolean isInner = Integer.parseInt((String)regtJSON.get("isInner"))==1?true:false ;
 			View.removeFavorViewsForUser(viewID, user,isInner,classID) ;
 		}else if(option.equals("addFavorite")){
			String str =  URLDecoder.decode(json,"utf-8");
			JSONObject regtJSON = (JSONObject) JSONValue.parse(str);
 			String user = (String)regtJSON.get("user") ;
 			String lang = (String)regtJSON.get("lang") ;
 			int classID = Integer.parseInt((String)regtJSON.get("classID"));
			boolean isInner =Integer.parseInt((String)regtJSON.get("isInner"))==1?true:false;
 			int viewID = Integer.parseInt((String)regtJSON.get("viewID")) ;
 			View.addFavorViewsForClassLangUser(viewID, user, classID, lang,isInner) ;
 		}
 		else if(option.equals("cancelTrash")){
			String str =  URLDecoder.decode(json,"utf-8");
			JSONObject regtJSON = (JSONObject) JSONValue.parse(str);
 			String user = (String)regtJSON.get("user") ;
 			int viewID = Integer.parseInt((String)regtJSON.get("viewID")) ;
 			int classID = Integer.parseInt((String)regtJSON.get("classID")) ;
 			boolean isInner = Integer.parseInt((String)regtJSON.get("isInner"))==1?true:false ;
 			View.removeTrashViewsForUser(viewID, user,isInner,classID) ;
 		}else if(option.equals("addTrash")){
			String str =  URLDecoder.decode(json,"utf-8");
			JSONObject regtJSON = (JSONObject) JSONValue.parse(str);
 			String user = (String)regtJSON.get("user") ;
 			String lang = (String)regtJSON.get("lang") ;
 			boolean isInner =Integer.parseInt((String)regtJSON.get("isInner"))==1?true:false;
			int classID = Integer.parseInt((String)regtJSON.get("classID"));
 			int viewID = Integer.parseInt((String)regtJSON.get("viewID")) ;
 			View.addTrashViewsForClassLangUser(viewID, user, classID, lang,isInner) ;
 		}
 		else if(option.equals("existBookmark")){
			String str =  URLDecoder.decode(json,"utf-8");
			JSONObject regtJSON = (JSONObject) JSONValue.parse(str);
 			String author = (String)regtJSON.get("author") ;
 			String name = (String)regtJSON.get("name") ;
 			String lang = (String)regtJSON.get("lang") ;
			int etype =Integer.parseInt((String)regtJSON.get("etype")) ;
 			int eid = Integer.parseInt((String)regtJSON.get("eid")) ;
 			
 			Bookmark bookmark = new Bookmark(name,author,lang,etype,eid);
 			int bmid = Bookmark.getBookmarkIdByNameAuthor(name, author);
 			if(bmid>0){
 				response.getWriter().print("exist") ;
 			}else{
 				response.getWriter().print("ok") ;
 			}
 		}
 		else if(option.equals("storeBookmark")){
			String str =  URLDecoder.decode(json,"utf-8");
			JSONObject regtJSON = (JSONObject) JSONValue.parse(str);
 			String author = (String)regtJSON.get("author") ;
 			String name = (String)regtJSON.get("name") ;
 			String lang = (String)regtJSON.get("lang") ;
			int etype =Integer.parseInt((String)regtJSON.get("etype")) ;
 			int eid = Integer.parseInt((String)regtJSON.get("eid")) ;
 			
 			Bookmark bookmark = new Bookmark(name,author,lang,etype,eid);
 			bookmark.serialize();
 			
 			EntityManagement.storeUserVisit(author, etype, eid, lang);
 		}
 		else if(option.equals("checkAuthor")){
			String str = URLDecoder.decode(json,"utf-8");
			JSONObject regtJSON = (JSONObject) JSONValue.parse(str);
 			String user = (String)regtJSON.get("user") ;
 			int userID = -1;
			try {
				userID = UserNameIDCache.getInstance().getUserID(user);
			} catch (Throwable e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
 			int vid =((Long)regtJSON.get("viewID")).intValue() ;
 			int groupID = View.getGroupIDByViewID(vid) ;
 			boolean isTranslatedView = View.isTranslatedView(vid);
 			
 			JSONObject result = new JSONObject();
 			try {
				boolean flag = Group.isMember(groupID, userID);
				if(flag){
					result.put("hasAuthor", "yes") ;
					result.put("gid",groupID);
					result.put("isTranslatedView",isTranslatedView);
					if(isTranslatedView){
						int transvid = View.getSrcTranlatedView(vid);
						result.put("srcvid", transvid);
					}
				}else{
					result.put("hasAuthor", "no") ;
					result.put("isTranslatedView",isTranslatedView);
				}
			} catch (Throwable e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			response.getWriter().print(result) ;
 			
 		}
 		else if(option.equals("viewDMList")){
			String str =  URLDecoder.decode(json,"utf-8");
			JSONObject regtJSON = (JSONObject) JSONValue.parse(str);
			int viewID = ((Long) regtJSON.get("viewID")).intValue();
			String lang = (String) regtJSON.get("lang");
			String user = (String) regtJSON.get("user");
			int etype =  ((Long) regtJSON.get("etype")).intValue();
			int eid =  ((Long) regtJSON.get("eid")).intValue();
			/* store popularity information */
			ViewManagement.storeUserVisit(user,etype,eid,lang, viewID);

			/* get the column displayed */
			int column = 1;
			/*
			 * If the user didn't custom the column ,use the setting of the
			 * group of the view
			 */
			if (viewID > 0) {
				column = View.getLayoutForUser(viewID, user);
				if (column < 0) {
					View view = View.getViewByViewId(viewID);
					String group = view.getGroup();
					column = View.getLayoutForUser(viewID, group);
					if (column < 0)
						column = 1;
				}
			}

			JSONArray resultArray = new JSONArray();
			ArrayList<DataMember> datamembers = null;

			if (viewID > 0)
				datamembers = View.getDataMembers(viewID);
			else if (viewID == -1) {
				HashSet<Integer> uris = EntityBrowsing.getEntityMembersWithoutSameas(
						etype, eid);
				datamembers = new ArrayList<DataMember>(
						View.getFowardMembers(uris));
			} else if (viewID == -2) {
				HashSet<Integer> uris = EntityBrowsing.getEntityMembersWithoutSameas(
						etype, eid);
				datamembers = new ArrayList<DataMember>(
						View.getBackwardMembers(uris));
			}

			ArrayList<URIResource> waitArray = new ArrayList<URIResource>();
			ArrayList<Integer> inverses = new ArrayList<Integer>();
			ArrayList<Integer> ids = new ArrayList<Integer>();
			for (int i = 0; i < datamembers.size(); i++) {
				int dmtype = 0;
				int dmid = 0;
				String name = null;
				int inverse = 0;
				DataMember datamember = datamembers.get(i);
				if (datamember instanceof CustomDataMember) {
					CustomDataMember dm = (CustomDataMember) datamember;
					dmtype = DataMember.CUSTOM_DATAMEMBER;
					dmid = dm.getID();
					name = View.getLabelInView(viewID, dmtype, dmid);
				} else {
					URIDataMember dm = (URIDataMember) datamember;
					dmtype = DataMember.URI_DATAMEMBER;
					dmid = dm.getID();
					if (dm.isInverse())
						inverse = 1;
					if (viewID > 0)
						name = View.getLabelInView(viewID, dmtype, dmid);
					else {
						try {
							name = URILabelCache.getInstance().getLabel(dmid,
									lang);
							if (name.equals("")) {
								/*
								 * not get the label of the lang ,need to
								 * dereference the doc and discard this data
								 * member
								 */
								String status = DBOperations
										.getValidStatus(dmid);
								URIResource uri_resource = ResourceFactory
										.getInstance().createURIResource(
												dm.getURI());
								if (!status.equals(URIResource.VALID)
										&& Crawler.getInstance().checkStatus(
												uri_resource) == Crawler.STATUS_UNSUBMITTED) {
									Crawler.getInstance().submitURI(
											uri_resource);
									Crawler.getInstance().promoteWeight(
											uri_resource, Element.LEVEL_1);
									waitArray.add(uri_resource);
									inverses.add(inverse);
									ids.add(dmid);
									continue;
								} else {
									name = URILabelCache.getInstance()
											.updateLabel(dmid, lang);
									if (name.equals("")) {
										name = URIUtil
												.getLocalname(uri_resource
														.getURI());
									}
								}
							}
						} catch (Throwable e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
				}

				JSONObject jsob = new JSONObject();
				jsob.put("dmtype", dmtype);
				jsob.put("dmid", dmid);
				jsob.put("name", name);
				jsob.put("inverse", inverse);
				resultArray.add(jsob);
			}

			/* wait and fetch valid datamembers */
			boolean waitflag = true;
			while (waitflag) {
				waitflag = false;
				for (URIResource resource : waitArray) {
					int status = Crawler.getInstance().checkStatus(resource);
					if (status != Crawler.STATUS_DONE) {
						waitflag = true;
						break;
					}
				}
				try {
					Thread.sleep(20);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			for (int i = 0; i < waitArray.size(); i++) {
				URIResource uri_res = waitArray.get(i);
				int inverse = inverses.get(i);
				int dmid = ids.get(i);
				String name = "";
				try {
					name = URILabelCache.getInstance().getLabel(dmid, lang);
					if (name.equals("")) {
						name = URIUtil.getLocalname(uri_res.getURI());
						if (lang.equals("en")) {
							URILabelCache.getInstance().setLabel(dmid, lang,
									name);
						} 
					}
				} catch (Throwable e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				JSONObject jsob = new JSONObject();
				jsob.put("dmtype", DataMember.URI_DATAMEMBER);
				jsob.put("dmid", dmid);
				jsob.put("name", name);
				jsob.put("inverse", inverse);
				resultArray.add(jsob);
			}

			JSONObject resob = new JSONObject();
			resob.put("column", column);
			resob.put("list", resultArray);
			response.getWriter().print(resob);
 		}else if(option.equals("viewDMValue")){
			String str = URLDecoder.decode(json,"utf-8");
			JSONObject regtJSON = (JSONObject) JSONValue.parse(str);
			int dmtype =((Long)regtJSON.get("dmtype")).intValue() ;
			int dmid = ((Long)regtJSON.get("dmid")).intValue() ;
			int inverse =  ((Long)regtJSON.get("inverse")).intValue() ;
 			String lang = (String)regtJSON.get("lang") ;
 			String genre = (String)regtJSON.get("genre") ;
 			int eid = ((Long)regtJSON.get("eid")).intValue() ;
 			String lastStatus = (String)regtJSON.get("status") ;
 			
 			int type = 0;
 			if(genre.equals(Entity.URI_ENTITY_Str))
 				type = Entity.URI_ENTITY;
 			else if(genre.equals(Entity.CUSTOM_ENTITY_Str))
 				type = Entity.CUSTOM_ENTITY;
 			else if(genre.equals(Entity.COLLECTION_Str))
 				 type =Entity.COLLECTION;
 			
 			/*get relevant origin uris in browsing*/
 			HashSet<Integer> uris = EntityBrowsing.getEntityMembersWithoutSameas(type, eid);
 			
 			HashSet<URIResource> entities = new HashSet<URIResource>();
 			for(Integer id:uris){
 				try {
					URIResource r = ResourceFactory.getInstance().createURIResource(URIIDCache.getInstance().getURI(id)) ;
					entities.add(r) ;
				} catch (Throwable e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
 			}
 			ViewReasoner viewReasoner = new ViewReasoner(entities);
 			
 			boolean waitData = false;
 			
 			HashSet<GroundAtom> reasoningRes = new HashSet<GroundAtom>();
 			
			Predicate pred = null;
			int arity = 0;
			if(dmtype==URIDataMember.URI_DATAMEMBER){
				arity = 2;
				try {
					URIResource pred_resource = ResourceFactory.getInstance().createURIResource(
					URIIDCache.getInstance().getURI(dmid)) ;
					pred  = new Predicate(pred_resource,arity);
				} catch (Throwable e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}else if(dmtype==URIDataMember.CUSTOM_DATAMEMBER){
				/****INTERNAL_URI_PREFIX+ "dm/group/isInner/classID/isCopy/name"****/
				CustomDataMember dm = CustomDataMember.getCustomDataMemberById(dmid) ;
				arity = dm.getArity();
				String name = dm.getName();
				String group = dm.getGroup();
				boolean isInner = dm.isInner();
				boolean isCopy = dm.isCopy();
				int classID = dm.getClassID();
				URIResource pred_resource =  ResourceFactory.getInstance().createCustomDatamemberURIResource(group, name,isInner,classID,isCopy);
				pred = new Predicate(pred_resource,arity);
			}
			//推理用到的相关数据源
			HashSet<String> srcDocs = new HashSet<String>();
			for(Integer uriID:uris){
				KnowledgeBase kb = new KnowledgeBase();
	 			kb.setViewReasoner(viewReasoner) ;
 				String uri = null;
				try {
					uri = URIIDCache.getInstance().getURI(uriID);
				} catch (Throwable e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
 				URIResource uriResource =ResourceFactory.getInstance().createURIResource(uri);
 				Constant c = new Constant(uriResource);
 				
 				ArrayList<Term> terms = new ArrayList<Term>();
 				if(inverse==0){
 					terms.add(c);
 					for(int i=1;i<arity;i++){
 						terms.add(new Variable("x"+i));
 					}
 				}else if(inverse==1){
 					/*origin uri datamember link is inverse*/
 					for(int i=0;i<arity-1;i++){
 						terms.add(new Variable("x"+i));
 					}
 					terms.add(c) ;
 				}
 			    
 				Atom<Term> query  = new Atom<Term>(pred,terms);
 				
 				HashSet<GroundAtom> part = new HashSet<GroundAtom>();
				try {
					part = kb.Evaluate(query,true,srcDocs);
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
 				reasoningRes.addAll(part) ;
 				if(!kb.isFinished()){
 					waitData = true;
 				}
 			}
			
			JSONArray docArray = new JSONArray();
			for(String doc:srcDocs){
				int docID = 0;
				try {
					docID = URIIDCache.getInstance().getURIID(doc, true);
				} catch (Throwable e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				JSONObject docObj = new JSONObject();
				docObj.put("id",docID);
				docObj.put("uri", doc);
				docArray.add(docObj);
			}
			
 			/*If the uri's label of lang is unknown, dereference the uri*/
 			JSONArray valueArray = new JSONArray();
 			int count =0;
 			
 			for(GroundAtom groudAtom:reasoningRes){
 				count++;
 				JSONObject jsob = new JSONObject();
 				ArrayList<Constant> array = groudAtom.getTerms();
 				if(arity==2){
 					String valueLabel = null;
 	 				int entityID =0;
 	 				String etype = null;
 					Resource resource = null;
 					String euri = null;
 					boolean needLabel = false;
					if (inverse == 0) {
				        Constant constant = array.get(1) ;
				        resource = constant.getResource();
					} else if (inverse == 1) {
						Constant constant = array.get(0) ;
				        resource = constant.getResource();
					}
					
					if(resource instanceof PlainLiteral){
						PlainLiteral literal = (PlainLiteral)resource;
						if(literal.getLanguageTag().startsWith(lang)){
							valueLabel = literal.getLexicalForm();
							etype = "l" ;
							entityID = valueLabel.hashCode();
						}else if(lang.equals("en")&&literal.getLanguageTag().equals("")){
							valueLabel = literal.getLexicalForm();
							etype = "l" ;
							entityID = valueLabel.hashCode();
						}else
							continue;
						
					}else if(resource instanceof TypedLiteral){
						Literal literal = (Literal)resource;
						valueLabel = literal.getLexicalForm();
						etype = "l" ;
						entityID = valueLabel.hashCode();
					}
					else if(resource instanceof BlankNode){
						/*remove blank nodes*/
						continue;
					}else{
						URIResource uri_resource =(URIResource)resource;
						euri = uri_resource.getURI();
						etype=Entity.URI_ENTITY_Str ;
						try {
							entityID = URIIDCache.getInstance().getURIID(uri_resource.getURI(), false) ;
						} catch (Throwable e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						try {
							valueLabel = URILabelCache.getInstance().getLabel(entityID, lang) ;
							if(valueLabel.equals("")){
								valueLabel = URIUtil.getLocalname(uri_resource.getURI()) ;
								/*not get the label of the lang ,need to dereference the doc
								 * and discard this result
								 * */
								String status = DBOperations.getValidStatus(entityID);
								if(!status.equals(URIResource.VALID)&&
										Crawler.getInstance().checkStatus(uri_resource)==Crawler.STATUS_UNSUBMITTED){
								      needLabel  =true;
								}
							}
						} catch (Throwable e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
					
					/*对于homepage等属性做特殊处理*/
					if(dmtype==URIDataMember.URI_DATAMEMBER){
						HashSet<Integer> directuriset = PropertyList.getDirectURIProperties();
						HashSet<Integer> directlabelset = PropertyList.getDirectLabelProperties();
						if(directuriset.contains(dmid)){
							jsob.put("directuri", 1) ;
							needLabel = false;
						}else if(directlabelset.contains(dmid)){
							jsob.put("directlabel", 1) ;
							needLabel = false;
						}
					}
					
					if(etype.equals(Entity.URI_ENTITY_Str )){
						if(euri.startsWith("http://")||euri.startsWith("https://")){
							if(euri.endsWith(".jpg")||euri.endsWith(".png")||euri.endsWith(".bmp")
							||euri.endsWith(".jpeg")||euri.endsWith(".gif")||euri.endsWith(".ico")){
								jsob.put("isimage", 1);
								needLabel = false;
							}
						}
					}
					jsob.put("valueLabel", valueLabel) ;
					jsob.put("etype",etype) ;
					jsob.put("eid", entityID) ;
					jsob.put("euri", euri);
					jsob.put("needLabel", needLabel);
					valueArray.add(jsob);
 				}else{
 					throw new IllegalArgumentException("The arity of predicate must be 2");
 				}
 			}
 			
// 			int fetchLabelNum = 0;
// 			for(GroundAtom groudAtom:reasoningRes){
// 				count++;
// 				JSONObject jsob = new JSONObject();
// 				ArrayList<Constant> array = groudAtom.getTerms();
// 				//当前取值时因为那个元素得到的
// 				int memberType = -1;
// 				int memberID = -1;
// 				String memberLabel = null;
// 				if(arity==2){
// 					String valueLabel = null;
// 	 				int entityID =0;
// 	 				String etype = null;
// 					Resource resource = null;
// 					String euri = null;
// 					URIResource memberResource = null;
//					if (inverse == 0) {
//				        Constant constant = array.get(1) ;
//				        resource = constant.getResource();
//				        memberResource = (URIResource)array.get(0).getResource();
//					} else if (inverse == 1) {
//						Constant constant = array.get(0) ;
//				        resource = constant.getResource();
//				        memberResource = (URIResource)array.get(1).getResource();
//					}
//					
//					//处理具有该取值的member
//					memberType = Entity.URI_ENTITY;
//					memberID = memberResource.getID();
//					memberLabel = memberResource.getLabel(memberID, lang);
//					
//					if(resource instanceof PlainLiteral){
//						PlainLiteral literal = (PlainLiteral)resource;
//						if(literal.getLanguageTag().startsWith(lang)){
//							valueLabel = literal.getLexicalForm();
//							etype = "l" ;
//							entityID = valueLabel.hashCode();
//						}else if(lang.equals("en")&&literal.getLanguageTag().equals("")){
//							valueLabel = literal.getLexicalForm();
//							etype = "l" ;
//							entityID = valueLabel.hashCode();
//						}else
//							continue;
//						
//					}else if(resource instanceof TypedLiteral){
//						Literal literal = (Literal)resource;
//						valueLabel = literal.getLexicalForm();
//						etype = "l" ;
//						entityID = valueLabel.hashCode();
//					}
//					else if(resource instanceof BlankNode){
//						/*remove blank nodes*/
//						continue;
//					}else{
//						URIResource uri_resource =(URIResource)resource;
//						euri = uri_resource.getURI();
//						etype=Entity.URI_ENTITY_Str ;
//						try {
//							entityID = URIIDCache.getInstance().getURIID(uri_resource.getURI(), false) ;
//						} catch (Throwable e) {
//							// TODO Auto-generated catch block
//							e.printStackTrace();
//						}
//						try {
//							valueLabel = URILabelCache.getInstance().getLabel(entityID, lang) ;
//							if(valueLabel.equals("")){
//								/*not get the label of the lang ,need to dereference the doc
//								 * and discard this result
//								 * */
//								String status = DBOperations.getValidStatus(entityID);
//								if(!status.equals(URIResource.VALID)&&
//										Crawler.getInstance().checkStatus(uri_resource)==Crawler.STATUS_UNSUBMITTED){
//									fetchLabelNum++;
//									//only fetch top k result labels
//									if (fetchLabelNum > ViewServlet.REASONING_RESULT_LABEL_FETCH_NUM) {
//										valueLabel = URIUtil
//												.getLocalname(uri_resource
//														.getURI());
//									} else {
//										waitForLabelExtract = true;
//										Crawler.getInstance().submitURI(
//												uri_resource);
//										Crawler.getInstance().promoteWeight(
//												uri_resource,
//												Element.LEVEL_1);
//										boolean wait = true;
//										while (wait) {
//											wait = false;
//											int labelstatus = Crawler
//													.getInstance().checkStatus(
//															uri_resource);
//											if (labelstatus != Crawler.STATUS_DONE) {
//												wait = true;
//											}
//											try {
//												Thread.sleep(20);
//											} catch (InterruptedException e) {
//												// TODO Auto-generated catch
//												// block
//												e.printStackTrace();
//											}
//										}
//										valueLabel = URILabelCache
//												.getInstance().updateLabel(
//														entityID, lang);
//										if(valueLabel.equals("")){
//											valueLabel = URIUtil.getLocalname(uri_resource.getURI()) ;
//										}
//									}
//								}else{
//									valueLabel = URILabelCache.getInstance().updateLabel(entityID, lang) ;
//									if(valueLabel.equals("")){
//										   valueLabel = URIUtil.getLocalname(uri_resource.getURI()) ;
//									}
//								}
//							}
//						} catch (Throwable e) {
//							// TODO Auto-generated catch block
//							e.printStackTrace();
//						}
//					}
//					
//					/*对于homepage等属性做特殊处理*/
//					if(dmtype==URIDataMember.URI_DATAMEMBER){
//						HashSet<Integer> directuriset = PropertyList.getDirectURIProperties();
//						HashSet<Integer> directlabelset = PropertyList.getDirectLabelProperties();
//						if(directuriset.contains(dmid)){
//							jsob.put("directuri", 1) ;
//						}else if(directlabelset.contains(dmid)){
//							jsob.put("directlabel", 1) ;
//						}
//					}
//					
//					if(etype.equals(Entity.URI_ENTITY_Str )){
//						if(euri.startsWith("http://")||euri.startsWith("https://")){
//							if(euri.endsWith(".jpg")||euri.endsWith(".png")||euri.endsWith(".bmp")
//							||euri.endsWith(".jpeg")||euri.endsWith(".gif")||euri.endsWith(".ico")){
//								jsob.put("isimage", 1);
//							}
//						}
//					}
//					
//					jsob.put("valueLabel", valueLabel) ;
//					jsob.put("etype",etype) ;
//					jsob.put("eid", entityID) ;
//					jsob.put("euri", euri);
//					jsob.put("memberType", memberType);
//					jsob.put("memberID", memberID);
//					jsob.put("memberLabel", memberLabel);
//					valueArray.add(jsob);
// 				}else{
// 					throw new IllegalArgumentException("The arity of predicate must be 2");
// 				}
// 			}
 			
 			JSONObject result = new JSONObject();
 			
 			/**
 			 * 通过两层来控制是否结束
 			 * 第一层是推理是否完结
 			 * 第二层是URI是否取到需要的Label
 			 * 因此理论上走了三步来下载文档
 			 */
 			String status = STATUS_STOP;
 			if(valueArray.size()>=ALTIMATE_REASONING_RESULT){
 				 status = STATUS_STOP;
 			}
 			else if(waitData){
 				status =STATUS_WAIT_DATA;
 			}
 			
 			result.put("status", status) ;
 			
 			result.put("values", valueArray) ;
 			result.put("srcDocs", docArray);
 			response.getWriter().print(result) ;
 		}else if(option.equals("viewSearch")){
			String str = URLDecoder.decode(json,"utf-8");
			JSONObject regtJSON = (JSONObject) JSONValue.parse(str);
			String kw = (String)regtJSON.get("kw") ;
			String lang = (String)regtJSON.get("lang") ;
			String user = (String)regtJSON.get("user") ;
			int etype = ((Long)(regtJSON.get("etype"))).intValue();
			int eid = ((Long)(regtJSON.get("eid"))).intValue();
			boolean isInner= Integer.parseInt((String)(regtJSON.get("isInner")))==1?true:false;
			int cid = Integer.parseInt((String)(regtJSON.get("cid")));
			ArrayList<ViewItem> array = null;
			array  = ViewEditing.kw2View(user, kw, lang, isInner, cid) ;
			JSONArray elements = new JSONArray();
			for(ViewItem item:array){
				JSONObject jsob = new JSONObject();
				
				int vid = item.getViewID();
				String name = item.getName();
				String category = item.getCategory();
				jsob.put("vid", vid) ;
				jsob.put("name", name);
				jsob.put("category", category);
		        elements.add(jsob) ;
			}
			System.out.println("vs:"+elements.toJSONString());
		    response.getWriter().print(elements) ;
 		}
	}
}
